package com.swxy.club.service.impl;





import cn.hutool.core.convert.Convert;
import cn.hutool.core.lang.Assert;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.alibaba.nacos.client.naming.utils.CollectionUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.swxy.club.dto.*;
import com.swxy.club.dto.Vo.ClubMemberVO;
import com.swxy.club.dto.Vo.ManagedClubVO;
import com.swxy.club.dto.Vo.UserClubVO;
import com.swxy.club.dto.dt.ClubMemberPageQuery;
import com.swxy.club.dto.dt.ClubQueryDTO;
import com.swxy.club.dto.dt.ClubRegisterDTO;
import com.swxy.club.dto.bo.CurrentUserBO;
import com.swxy.club.dto.dt.UpdateMemberRoleDTO;
import com.swxy.club.enums.AuditStatus;
import com.swxy.club.dto.dt.ClubRoleConstants;
import com.swxy.club.enums.ClubMemberRole;
import com.swxy.club.enums.ClubStatus;
import com.swxy.club.enums.Gender;
import com.swxy.club.feignClient.UserServiceFeignClient;
import com.swxy.club.mapper.ClubMapper;
import com.swxy.club.mapper.ClubUserRoleMapper;
import com.swxy.club.result.Result;
import com.swxy.club.service.ClubApplicationService;
import com.swxy.club.service.ClubService;
import com.swxy.club.utils.UserContext;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.EnumUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
public class ClubServiceImpl extends ServiceImpl<ClubMapper, Club> implements ClubService{

    @Autowired
    private ClubApplicationService clubApplicationService;

    @Autowired
    private ClubUserRoleMapper clubUserRoleMapper;
    @Autowired
    private UserServiceFeignClient userServiceFeignClient;


    @Transactional
    @Override
    public void registerClub(ClubRegisterDTO dto) {

        // 从token中获取操作人ID
        CurrentUserBO currentUser = UserContext.getCurrentUser();
//        检查社团是否存在
        LambdaQueryWrapper<Club> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(Club::getName, dto.getName());
        Assert.isFalse(this.getBaseMapper().selectCount(queryWrapper) > 0,"社团名称已存在");

//        创建社团记录
        Club club = new Club();
        club.setName(dto.getName());
        club.setDescription(dto.getDescription());
        club.setCategoryId(dto.getCategoryId());

        // 设置为暂停状态
        club.setStatus(ClubStatus.PAUSED);
        // 设置为待审核状态
        club.setAppliStatus(AuditStatus.PENDING);
        // 初始成员数
        club.setMemberCount(dto.getMemberCount());
        // 设置创建人
        club.setCreateId(currentUser.getId());
        // 设置更新人
        club.setUpdateId(currentUser.getId());
//        保存社团记录
        this.getBaseMapper().insert(club);

//       创建社团申请记录
        ClubApplication application = new ClubApplication();
        application.setCulbId(club.getClubId().intValue());
        application.setUserId(currentUser.getId());
        application.setApplyReason(dto.getApplyReason());
        application.setRefuseReason(null);
        application.setStatus(AuditStatus.PENDING);
        // 初始无处理人
        application.setOperateId(null);
        application.setCreateId(currentUser.getId());
        application.setUpdateId(currentUser.getId());
        application.setCreateTime(LocalDateTime.now());
        application.setUpdateTime(LocalDateTime.now());
        clubApplicationService.save(application);
    }

    @Override
    public Page<Club> getClubPage(ClubQueryDTO queryDTO) {
        Page<Club> page = new Page<>(queryDTO.getPageNum(), queryDTO.getPageSize());
        // 手动设置 COUNT 查询（可选）
        // 关闭自动优化 COUNT SQL
        page.setOptimizeCountSql(false);
        // 确保进行 COUNT 查询
        page.setSearchCount(true);

        LambdaQueryWrapper<Club> queryWrapper = new LambdaQueryWrapper<>();

        if (StringUtils.isNotBlank(queryDTO.getName())) {
            queryWrapper.like(Club::getName, queryDTO.getName());
        }
        if (queryDTO.getCategoryId() != null) {
            queryWrapper.eq(Club::getCategoryId, queryDTO.getCategoryId());
        }
        if (StringUtils.isNotBlank(queryDTO.getStatus())) {
            queryWrapper.eq(Club::getStatus, queryDTO.getStatus());
        }
        queryWrapper.orderByDesc(Club::getCreateTime);

        // 使用 selectPage 进行分页查询
        return this.getBaseMapper().selectPage(page, queryWrapper);
    }


    @Override
    public Club getUserByClubIdNumber(String clubId) {
        Club club = this.getById(clubId);
        Assert.notNull(club,"社团不存在");
        return club;
    }

    @Transactional
    @Override
    public void updateClubStatus(Long clubId, String status) {
        // 1. 从token中获取操作人ID

        CurrentUserBO currentUser = UserContext.getCurrentUser();
        Long operatorId= currentUser.getId();

        // 2. 验证状态值是否合法
        Assert.isTrue(status == null || EnumUtils.isValidEnum(ClubStatus.class, status), "非法状态");

        // 3. 查询社团信息
        Club updatclub = this.getById(clubId);
        Assert.notNull(updatclub, "社团不存在");

        // 4. 检查当前状态是否允许修改,如果是待审核状态或拒绝状态，则不允许修改
        Assert.isFalse(updatclub.getAppliStatus() == AuditStatus.PENDING || updatclub.getAppliStatus() == AuditStatus.REJECTED, "社团状态不允许修改");
        // 5. 检查社团是否已解散，解散的社团不允许修改
        Assert.isTrue(updatclub.getStatus() != ClubStatus.DISBANDED, "社团已解散，不允许修改");
        // 6. 更新社团状态

        updatclub.setStatus(ClubStatus.valueOf(status));
        updatclub.setUpdateId(operatorId);
        updatclub.setUpdateTime(LocalDateTime.now());
        this.updateById(updatclub);
    }

    /**
     * 直接加入社团
     * @param clubId
     */
    @Transactional
    @Override
    public void joinClub(Long clubId) {
        CurrentUserBO currentUser = UserContext.getCurrentUser();
        Long userId = currentUser.getId();
        // 1. 验证社团是否存在且状态正常
        Club club = this.getById(clubId);

        Assert.notNull(club, "社团不存在");
        Assert.isTrue(!ClubStatus.ACTIVE.equals(club.getStatus()), "社团状态异常");

        // 2. 检查用户是否已加入该社团
        LambdaQueryWrapper<ClubUserRole> query = new LambdaQueryWrapper<>();
        query.eq(ClubUserRole::getClubId, clubId)
                .eq(ClubUserRole::getUserId, userId);
        Assert.isTrue(clubUserRoleMapper.selectCount(query) > 0, "用户已加入该社团");
        // 3. 创建社团成员记录(默认普通成员角色)
        ClubUserRole member = new ClubUserRole();
        member.setClubId(clubId.intValue());
        member.setUserId(userId.intValue());
        // 设置为普通成员
        member.setRoleCode(ClubRoleConstants.MEMBER);
        member.setCreateId(userId);
        member.setCreateTime(LocalDateTime.now());
        member.setUpdateId(userId);
        member.setUpdateTime(LocalDateTime.now());
       Assert.isTrue(clubUserRoleMapper.insert(member) > 0, "加入社团失败");
    }

    /**
     * 获取社团成员列表
     * @param clubId
     * @return
     */
    @Override
    @Transactional
    public List<ClubMemberVO> getClubMembers(Long clubId) {
        // 查询社团成员关系
        LambdaQueryWrapper<ClubUserRole> memberQuery = new LambdaQueryWrapper<>();
        memberQuery.eq(ClubUserRole::getClubId, clubId.intValue())
                .orderByAsc(ClubUserRole::getId);
        List<ClubUserRole> memberRelations = clubUserRoleMapper.selectList(memberQuery);
        if (memberRelations.isEmpty()) {
            return Collections.emptyList();
        }
        // 查询用户信息
        List<Long> userIds = memberRelations.stream()
                .map(ClubUserRole::getUserId)
                .map(Integer::longValue)
                .collect(Collectors.toList());
        // 批量查询用户信息
        Result result = userServiceFeignClient.selectUsers(userIds);
        List<User> users = Convert.toList(User.class, result.getData());
        // 构建返回结果
        List<ClubMemberVO> memberVOs = new ArrayList<>();
        for (ClubUserRole relation : memberRelations) {
            Long userId = relation.getUserId().longValue();
            // 直接遍历查找匹配的用户
            for (User user : users) {
                if (user.getId().equals(userId)) {
                    ClubMemberVO vo = new ClubMemberVO();
                    vo.setUserId(userId);
                    vo.setRealName(user.getRealName());
                    vo.setGender(user.getGender() != null ? user.getGender() : Gender.MALE);
                    vo.setClubRole(relation.getRoleCode());
                    vo.setJoinTime(relation.getCreateTime());
                    vo.setAvatar(user.getAvatar());
                    memberVOs.add(vo);
                    break;
                }
            }
        }
        return memberVOs;
    }

    /**
     * 分页查询社团成员
     * @param query
     * @return
     */
    @Override
    public Page<ClubMemberVO> getClubMembersByPage(ClubMemberPageQuery query) {
        // 构建分页参数
        Page<ClubMemberVO> page = new Page<>(query.getPageNum(), query.getPageSize());

        // 构建查询条件
        LambdaQueryWrapper<ClubUserRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ClubUserRole::getClubId, query.getClubId().intValue());

        // 添加角色筛选条件
        if (StringUtils.isNotBlank(query.getRoleCode())) {
            queryWrapper.eq(ClubUserRole::getRoleCode, query.getRoleCode());
        }

        // 查询社团成员关系
        List<ClubUserRole> memberRelations = clubUserRoleMapper.selectList(queryWrapper);
        if (CollectionUtils.isEmpty(memberRelations)) {
            return page.setRecords(Collections.emptyList()); // 返回空分页结果
        }

        // 提取用户ID集合
        List<Long> userIds = memberRelations.stream()
                .map(ClubUserRole::getUserId)
                .map(Integer::longValue)
                .collect(Collectors.toList());

        // 批量查询用户信息
        Result result = userServiceFeignClient.selectUsers(userIds);
        List<User> users = Convert.toList(User.class, result.getData());

        // 构建用户ID到用户对象的映射
        Map<Long, User> userMap = users.stream()
                .collect(Collectors.toMap(User::getId, Function.identity()));

        // 构建返回结果并应用筛选条件
        List<ClubMemberVO> memberVOs = memberRelations.stream()
                .map(relation -> {
                    Long userId = relation.getUserId().longValue();
                    User user = userMap.get(userId);

                    if (user == null) {
                        return null;
                    }

                    // 姓名模糊筛选
                    if (StringUtils.isNotBlank(query.getRealName())) {
                        if (!user.getRealName().contains(query.getRealName())) {
                            return null;
                        }
                    }

                    // 性别筛选
                    if (query.getGender() != null && !query.getGender().equals(user.getGender())) {
                        return null;
                    }

                    ClubMemberVO vo = new ClubMemberVO();
                    vo.setUserId(userId);
                    vo.setRealName(user.getRealName());
                    vo.setGender(user.getGender());
                    vo.setClubRole(relation.getRoleCode());
                    vo.setJoinTime(relation.getCreateTime());
                    vo.setAvatar(user.getAvatar());
                    return vo;
                })
                .filter(Objects::nonNull)
                .collect(Collectors.toList());
        // 设置分页结果
        return page.setRecords(memberVOs)
                .setTotal(memberVOs.size());
    }

    @Override
    public void deleteClubMember(Long clubId, Long userId) {
//        构建删除条件
        LambdaQueryWrapper<ClubUserRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ClubUserRole::getClubId, clubId.intValue())
                .eq(ClubUserRole::getUserId, userId.intValue());
//        检查用户是否为社团成员
        ClubUserRole relation = clubUserRoleMapper.selectOne(queryWrapper);
        Assert.notNull(relation, "用户不是社团成员");
//        检查用户是否为社团创建人
        CurrentUserBO currentUser = UserContext.getCurrentUser();
        Assert.isTrue(currentUser.getId().equals(userId), "创建人不能退出社团");
//        检查社团是否已解散
        Club club = this.getById(clubId);
        Assert.isTrue(club.getStatus() != ClubStatus.DISBANDED, "社团已解散");
        // 删除社团成员关系
        clubUserRoleMapper.delete(queryWrapper);
    }

    @Override
    public ClubMemberVO getClubMember(Long clubId, Long userId) {
//        构建查询条件
        LambdaQueryWrapper<ClubUserRole> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ClubUserRole::getClubId, clubId.intValue())
                .eq(ClubUserRole::getUserId, userId.intValue());
//        查看用户的详细信息返回给前端
        ClubUserRole relation = clubUserRoleMapper.selectOne(queryWrapper);
        Assert.notNull(relation, "用户不是社团成员");
        Result result = userServiceFeignClient.getUser(userId);
        User user = Convert.convert(User.class, result.getData());
        ClubMemberVO vo = new ClubMemberVO();
        vo.setUserId(userId);
        vo.setRealName(user.getRealName());
        vo.setGender(user.getGender());
        vo.setClubRole(relation.getRoleCode());
        vo.setJoinTime(relation.getCreateTime());
        vo.setAvatar(user.getAvatar());
        return vo;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void updateClubMemberRole(UpdateMemberRoleDTO dto) {
        // 获取当前用户
        CurrentUserBO currentUser = UserContext.getCurrentUser();

        // 查询要修改的记录
        ClubUserRole relation = clubUserRoleMapper.selectOne(
                new LambdaQueryWrapper<ClubUserRole>()
                        .eq(ClubUserRole::getClubId, dto.getClubId())
                        .eq(ClubUserRole::getUserId, dto.getUserId())
        );
        Assert.notNull(relation, "用户不是社团成员");

        // 权限检查
        ClubUserRole currentUserRole = clubUserRoleMapper.selectOne(
                new LambdaQueryWrapper<ClubUserRole>()
                        .eq(ClubUserRole::getClubId, dto.getClubId())
                        .eq(ClubUserRole::getUserId, currentUser.getId())
        );
        Assert.notNull(currentUserRole, "您不是该社团成员");
        // 特殊角色保护
        Assert.isTrue(!ClubMemberRole.PRESIDENT.equals(dto.getNewRoleCode()), "社长不能修改为其他角色");

        // 验证新角色
        Assert.isTrue(!ClubMemberRole.isValid(dto.getNewRoleCode()),"非法角色");

        // 执行更新
        UpdateWrapper<ClubUserRole> updateWrapper = new UpdateWrapper<>();
        updateWrapper.eq("id", relation.getId())
                .set("role_code", dto.getNewRoleCode())
                .set("update_id", currentUser.getId())
                .set("update_time", LocalDateTime.now());

        int affectedRows = clubUserRoleMapper.update(null, updateWrapper);
        Assert.isTrue(affectedRows > 0, "更新失败");
    }

    @Override
    public List<UserClubVO> getClubsByUserId(Long userId) {
        // 1. 查询用户加入的所有社团关系
        List<ClubUserRole> relations = clubUserRoleMapper.selectList(
                new LambdaQueryWrapper<ClubUserRole>()
                        .eq(ClubUserRole::getUserId, userId.intValue())
        );

        if (relations.isEmpty()) {
            return Collections.emptyList();
        }

        // 2. 获取社团ID列表
        List<Integer> clubIds = relations.stream()
                .map(ClubUserRole::getClubId)
                .collect(Collectors.toList());

        // 3. 批量查询社团信息
        List<Club> clubs = this.getBaseMapper().selectList(
                new LambdaQueryWrapper<Club>()
                        .in(Club::getClubId, clubIds)
        );

        // 4. 构建社团ID到社团对象的映射
        Map<Integer, Club> clubMap = clubs.stream()
                .collect(Collectors.toMap(
                        club -> club.getClubId().intValue(),
                        Function.identity()
                ));

        // 5. 构建社团ID到用户角色的映射
        Map<Integer, String> roleMap = relations.stream()
                .collect(Collectors.toMap(
                        ClubUserRole::getClubId,
                        ClubUserRole::getRoleCode
                ));

        // 6. 组装返回结果
        return clubs.stream()
                .map(club -> {
                    UserClubVO vo = new UserClubVO();
                    vo.setClubId(club.getClubId());
                    vo.setClubName(club.getName());
                    vo.setDescription(club.getDescription());
                    vo.setMemberCount(club.getMemberCount());
                    vo.setStatus(club.getStatus());
                    vo.setRole(roleMap.get(club.getClubId().intValue()));
                    vo.setJoinTime(getJoinTime(relations, club.getClubId()));
                    return vo;
                })
                .collect(Collectors.toList());
    }

    @Override
    public List<ManagedClubVO> getManagedClubsByUserId(Long userId) {
        // 1. 查询用户担任管理角色的社团关系
        List<ClubUserRole> managementRelations = clubUserRoleMapper.selectList(
                new LambdaQueryWrapper<ClubUserRole>()
                        .eq(ClubUserRole::getUserId, userId.intValue())
                        .in(ClubUserRole::getRoleCode,
                                Arrays.asList(
                                        ClubRoleConstants.PRESIDENT
                                ))
        );

        if (managementRelations.isEmpty()) {
            return Collections.emptyList();
        }

        // 2. 获取社团ID列表
        List<Integer> clubIds = managementRelations.stream()
                .map(ClubUserRole::getClubId)
                .collect(Collectors.toList());

        // 3. 批量查询社团信息
        List<Club> clubs = this.getBaseMapper().selectList(
                new LambdaQueryWrapper<Club>()
                        .in(Club::getClubId, clubIds)
        );

        // 4. 构建社团ID到社团对象的映射
        Map<Integer, Club> clubMap = clubs.stream()
                .collect(Collectors.toMap(
                        club -> club.getClubId().intValue(),
                        Function.identity()
                ));

        // 5. 构建社团ID到用户角色的映射
        Map<Integer, String> roleMap = managementRelations.stream()
                .collect(Collectors.toMap(
                        ClubUserRole::getClubId,
                        ClubUserRole::getRoleCode
                ));

        // 6. 组装返回结果
        return managementRelations.stream()
                .map(relation -> {
                    Club club = clubMap.get(relation.getClubId());
                    ManagedClubVO vo = new ManagedClubVO();
                    vo.setClubId(club.getClubId());
                    vo.setClubName(club.getName());
                    vo.setDescription(club.getDescription());
                    vo.setMemberCount(club.getMemberCount());
                    vo.setStatus(club.getStatus());
                    vo.setRole(relation.getRoleCode());
                    vo.setRoleAssignTime(relation.getCreateTime());
                    return vo;
                })
                .collect(Collectors.toList());
    }

    private LocalDateTime getJoinTime(List<ClubUserRole> relations, Long clubId) {
        return relations.stream()
                .filter(r -> r.getClubId().equals(clubId.intValue()))
                .findFirst()
                .map(ClubUserRole::getCreateTime)
                .orElse(null);

    }


}